//
// Created by Chiro on 2022/10/2.
//

/**
 * 此文件能够依照宏配置决定当前模块的运行模式：
 * 1. RTL 模式，仅运行 Verilator
 * 2. Software Model 模式：仅运行软件模型
 * 3. Difftest 模式：RTL 和 Software Model 同时运行，并且进行差分测试
 */

#ifndef CHISEL_X_ASK_HPP
#define CHISEL_X_ASK_HPP

#include <common.h>
#include <ASK.h>
#include <verilated_fst_c.h>

#ifndef USE_MODEL
#include <verilated.h>
#else

#include <model.h>

#ifndef IS_DIFF_ON
#define IS_DIFF_ON IS_DIFF(ASK)
#endif
#define VerilatedTargetASK MUXDEF(IS_DIFF_ON, VerilatedDiff<ASK>, VerilatedFake)

class ASK_sm : public VerilatedTargetASK {
public:
/*
  val io = IO(new Bundle {
    val clockOffset = Input(UInt(8.W))
    val dataSource = Input(UInt(8.W))
    val start = Input(Bool())
    val dacOut = Output(UInt(8.W))
  })
*/
  uint8_t io_clockOffset{}, io_dataSource{}, io_start{}, io_datOut{};
  uint8_t cnt{};

  ASK_sm() : VerilatedTargetASK() {}

#if IS_DIFF_ON

  void dut_load() override {
    dut->clock = clock, dut->reset = reset;
    dut->eval();
  }

  void dut_apply() override {
    clock = dut->clock;
    reset = dut->reset;
  }

  bool dut_check() override {
    return true;
  }

#endif

  void eval() override {
    static uint8_t clock_last = 1;
    IFDEF(IS_DIFF_ON, dut_load());
    // on rising edge
    if (clock_last == 0 && clock == 1) {
    }
    clock_last = clock;
    IFDEF(IS_DIFF_ON, Assert(dut_check(), "DUT Assert Failed"));
  }
};

#define ASK ASK_sm
#ifndef Verilated
#define Verilated VerilatedTargetASK
#endif
#endif

#endif //CHISEL_X_ASK_HPP
